/*
 * Copyright 2009-2010 the original author or authors.
 *
 * Licensed under the Apache license, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.internna.iwebjtracker.subversion.server.model;

import java.util.Date;
import javax.activation.FileTypeMap;
import javax.activation.MimetypesFileTypeMap;
import org.internna.iwebjtracker.model.DefaultConnectionDetails;
import org.internna.iwebjtracker.model.DefaultModule;
import org.internna.iwebjtracker.model.DefaultProject;
import org.internna.iwebjtracker.model.DefaultVersion;
import org.internna.iwebjtracker.model.ItemDataImpl;
import org.internna.iwebjtracker.model.TrackerUser;
import org.internna.iwebjtracker.server.scm.model.ItemData;
import org.internna.iwebjtracker.server.scm.model.ItemInfo;
import org.tmatesoft.svn.core.SVNNodeKind;
import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.wc.SVNInfo;
import static org.internna.iwebmvc.utils.StringUtils.hasText;
import static org.internna.iwebmvc.utils.StringUtils.getFilenameExtension;

/**
 * A wrapper for "svn info" properties.
 *
 * @author Jose Noheda
 * @since 1.0
 */
public final class SVNKitItemInfo implements ItemInfo<DefaultConnectionDetails, DefaultModule, DefaultVersion, TrackerUser, DefaultProject>  {

    private static final FileTypeMap mimes = MimetypesFileTypeMap.getDefaultFileTypeMap();

    private final SVNInfo info;
    private ItemDataImpl itemData;
    private final DefaultProject project;

    public SVNKitItemInfo(SVNInfo info, DefaultProject project) {
        this.info = info;
        this.project = project;
    }

    /**
     * @return null unless info was established
     */
    @Override public String getAbsolutePath() {
        return info == null ? null : info.getPath();
    }

    /**
     * Obtains the absolute path and tries to infer the mime type
     * from the application configured mimes in the mimes.types file (META-INF in model project)
     */
    @Override public String getMimeType() {
        String extension = getFilenameExtension(getAbsolutePath());
        return hasText(extension) ? mimes.getContentType("." + extension) : null;
    }

    /**
     * @return null unless info was established
     */
    @Override public Date getLastModified() {
        return info == null ? null : info.getTextTime();
    }

    /**
     * Unsupported yet.
     */
    @Override public Date getCreation() {
        throw new UnsupportedOperationException();
    }

    /**
     * @return -1 unless info was established
     */
    @Override public long getSizeInBytes() {
        return info == null ? -1 : info.getRepositorySize();
    }

    /**
     * Unsupported yet.
     */
    @Override public String getLastCommitMessage() {
        throw new UnsupportedOperationException();
    }

    /**
     * @return null unless info was established
     */
    @Override public String getLastCommitUser() {
        return info == null ? null : info.getAuthor();
    }

    /**
     * Accessor method.
     */
    @Override public ItemData getData() {
        return itemData;
    }

    /**
     * Accessor method that only accepts ItemDataImpl instances.
     */
    @Override public void setData(ItemData data) {
        if (data instanceof ItemDataImpl) {
            setItemData((ItemDataImpl) itemData);
        }
    }

    /**
     * Accessor method.
     */
    public void setItemData(ItemDataImpl itemData) {
        this.itemData = itemData;
    }

    /**
     * @return false unless info was established
     */
    @Override public boolean isDirectory() {
        return info == null ? false : SVNNodeKind.DIR.equals(info.getKind());
    }

    /**
     * @return false unless info was established
     */
    public boolean isRepositoryURL() {
        return info != null && info.getRepositoryRootURL().equals(info.getURL());
    }

    /**
     * If the item info is available the item exists in Subversion.
     * @return true
     */
    @Override public boolean exists() {
        return true;
    }

    /**
     * @return null unless info was established
     */
    public SVNURL getUrl() {
        return info != null ? info.getURL() : null;
    }

    /**
     * Accessor method.
     */
    @Override public DefaultProject getProject() {
        return project;
    }

}
